<?

/*** Инициализация класса Site ***/ 
	
	$cfg = Site::$Config = & Core::$Modules['site'];
	//pr( Core::$Modules);
	// pr($cfg);
	
	
	// перенести в модуль темы... либо отображать темы в настройках только по разрешению... (???) 
	// загружаем конфиги темы дизайна
	Site::$Theme = (object)read_array( 
		$cfg->design_dir .'/design_config.php'
	);
	
	if (val($cfg->theme) && $theme_settings = read_array(
		SETTINGS_DIR."/theme_{$cfg->theme}.php" // SETTINGS_DIR."/design.php"
		))
		Site::$Theme = array_merge(Site::$Theme, $theme_settings);
	
	Site::$Theme = (object)Site::$Theme;
	
	// pr($cfg);
	// pr(Site::$Theme);
	//pr(Site::$Config);
	$fields= array_flip(Db::get_fields('#site_pages'));
	unset($fields['content']);
	$fields = implode(',', array_flip($fields));
	Site::$pages_list_fields = $fields; 
	//pr($fields);

	
/*** Описание класса Site ***/ 	
	
class Site 
{
	// наиболее часто используемые поля-свойства страниц для использования в выборке из базы данных для построения меню, и для поиска родительских и дочерних страниц
	static $pages_list_fields = ''; 
	
	
	// объект с текущими настрйоками модуля Site
	static public $Config = null;
		
	// настройки активной темы дизайна
	static public $Theme = array();
		
	// генерация страниц для админки
	static public
    function admin_controller(&$Page)
	{
		//pr($Page);
		//pr($Page->action);

		$module_url = $Page->action->module_url;
		//pr($module_url);
		
		switch ($Page->action->id)
		{
			case ('pages'):
				
				// фикcируем текущий адрес как возратный URL
				ReturnURL::set(); 
				
				$Page->toolbar_id = 'pages';
				//pr($Page);
				
				$Page->data = Site::get_pages();
				//pr($Page->data);
				
				break;
				
				
			case ('edit_page'):	
				$Page->toolbar_id = 'pages';
				
				#
				$page_id = val(Core::$Request->args[0]);
				//pr(Core::$Request);
				
				if ($page_id)
					$Page->data = Site::get_page($page_id);
				else	
					$Page->data = Site::get_page_default();
				//pr($Page->data);
				//pr($_POST['data']);
				
				
				
				$Page->error='';
				
				if (!empty($_POST['data']))
				{
					
					// загружаем файлы из формы
					Files::upload(array(
						// размешаем загружать только картинки
						'allowed_ext' => array('jpg','gif','png'),
						// свой путь для загрузки картинок 
						'upload_dir'	=> DATA_DIR .'/files/_pages', 
						));
					
					
					$post_data = $_POST['data'];
					// pr($_POST);
					// pr($post_data);
					
					// создаем несуществующие, но обязательные поля 
					if (empty($post_data['modules']))
						$post_data['modules'] = '';
			
					if (empty($post_data['show']))
						$post_data['show'] = 0;
					
					if (empty($post_data['show_in_menu']))
						$post_data['show_in_menu'] = '';
					
					// проверяем на ошибочные значения
					if (empty($post_data['title']))
						$Page->error .= '<div>Название страницы не может быть пустым</div>';
					
					// прибавляем данные из формы к полному набору данных
					$Page->data = (object)array_merge((array)$Page->data, (array)$post_data);
					// pr($Page->data);
					
					// если нет ошибок - записываем страницу в базу
					if (!$Page->error) 
						$page_id = Site::save_page($Page->data); //TODO: получать id для новой страницы
					//pr($Page->error);
					
					
					
					// редиректим на список страниц или  возвращаемся к форме (если была нажата кнопка "сохранить и продолжить редактироание")
					if (!$Page->error) 
					{
						if (isset($_POST['save']))
							redirect($module_url.'/edit_page/'.$page_id);
						else
							ReturnURL::redirect($module_url.'/pages/');	
					}
						
				} //end  if(!empty($_POST['page']))
				
				//$Page->data = (object)$Page->data;
				//pr($Page->data);
				
				break;
		
			case ('delete_page'):
					$page_id = @Core::$Request->args[0];
					
					// :TODO: здесь нужно ввести доп. защиту от неявного удаления старницы от имени администратора (через xss атаку). Напримр, выводить сначала страницу с вопросом и класть в сессию хэш, а затем удалять, только если хеш удаления верный 
					// :TODO: заменит удаление на перемещение в корзину (либо сделать модулем)
					if ($page_id) Site::delete_page($page_id);
					ReturnURL::redirect($module_url.'/pages/');
				break;	
				
				
			case ('toggle_page'):
					$page_id = @Core::$Request->args[0];
					if ($page_id) Site::toggle_page($page_id);
					
					ReturnURL::redirect($module_url.'/pages/');
				break;	
				
				
			case ('page_position'):
					$page_id 	= @Core::$Request->args[0];
					$position 	= @Core::$Request->args[1];
					if ($page_id && isset(Core::$Request->args[1]))
						Site::page_position($page_id, $position);
					
					
					ReturnURL::redirect($module_url.'/pages/');
					
					
					
					
				break;	
				
				
			case ('settings'):
				//pr(self::$Config);
				Admin::action_settings(self::$Config->id);
				
				break;	
			
		}	
		
	
	}
	
	
    static public
    function action_page(&$Page)
    {
        
		
		
		$data =& $Page->data ;
		$data = Site::get_page($Page->id);
        
		
		// :TODO: здесь нужно проверить права пользователя на доступ к запрошенной странице
		//if (!Site::page_access($Request->path, $User))
			 //return self::action_error403();
		
		
		// :TODO: в будущем можно переделать систему виджетов - каждый модуль может регистрировать свои вижеты, указывая для них функции и облатси применимости, а также уровень доступа
		
		
		
		
		
		// вычисляем заголвок для текста - он будет пустой, если в первом абзаце контента используется H1
		$data->h1 = $data->title;
		if (strstr( $data->content , '</h1>' )) $data->h1='';
		
		
		
		
		// pr($data);
		
		
		// вычисляем все виджеты, прикрепленные к обрабатываемой странице 
		foreach ($data->widgets as $widget_id => $widget_params)
		{
			
			$widget_content = View::get_widget($widget_id , $widget_params.'&page_id='.$Page->id);
		
			// вставляем контент виджета вместо макропеременной, либо в конец контента ... 
			$widget_var = Site::$Config->widget_var;
			if (!$widget_var) $widget_var = '[%%widget_id%%]';
			
			//pr($widget_var);
			
			$widget_var =  str_replace('%widget_id%', $widget_id ,$widget_var);
			
			// pr($widget_var);
			
			if (strstr($data->content, $widget_var))
				$data->content = str_replace($widget_var, $widget_content, $data->content );
			else	
				$data->content .= $widget_content;
		
		}	
			
		
		
		
		//////////////////////////////////////////////////
		// корректируем старые картинки в контенте  	//
		// (можно удалить в полностью новой версии CMS)	// 
		//////////////////////////////////////////////////
		$data->content = str_replaces(
			$data->content,
			array(
				'/system/public/thumb.php' => '/system/public/php/thumb.php',
				'data/inc/thumb.php'=> 'system/public/php/thumb.php',
				'img=files/'		=> 'img=/data/files/',
				'img=/files/'		=> 'img=/data/files/',
				'"files/'			=> '"/data/files/',
				)
		);
		
		
		

				
		//pr($data);
        
        // $Page->data     = $data;
		//$Page->total_records = $total_count;
		// pr( $data->content, preg_find('!<h1(?:|\s[^>]*)>(.*)</h1>!i', $data->content));
		
		// вычисляем свойства для неглавной страницы
        if (empty($Page->is_index))
		{
			// вычисляем текст для заголовка
			// $Page->h1	= val($data->h1, $data->title);
			$Page->h1	 = $data->h1;
			
			// вычисляем текст для TITLE
			if ($data->page_title)
				$Page->title = $data->page_title;
			
			else
			if (strstr( $data->content , '</h1>' )) 
				// извлекаем первый заголовок из содержимого страницы
				$Page->title = 	preg_find('!<h1(?:|\s[^>]*)>(.*)</h1>!i', $data->content);
			else 
				$Page->title = 	$data->title;
			
			$Page->title = strip_tags($Page->title);
			
			
			
			
			if ($Page->site_title)
				$Page->title .= ' - '.$Page->site_title;
			
			$Page->title = strip_tags($Page->title);		
		}	

		if(!GET('template') && $data->page_template)
			$Page->page_template = Site::$Config->design_dir ."/" . $data->page_template;

		// pr($Page->page_template);
		// pr($data->page_template);
		
    }
    
   
	
	
	static public
    function action_error404(&$Page)
    {
		header('HTTP/1.1 404 Not Found');
		$Page->error = 404;
		
		// если в настройках задана страница 404 - показываем её
		if (!empty(Site::$Config->error404_page_id)
			&& self::page_exists_id(Site::$Config->error404_page_id)
			)
		{
			$Page->id = Site::$Config->error404_page_id;
			self::action_page($Page);
		}
		else
		{
			if (!empty(Site::$Config->error404_content))
				$Page->data->content  = Site::$Config->error404_content;
			else
				$Page->data->content = '<font color=#ff0000>Ошибка! Запрошенная страница не найдена.</font>';
			
			$Page->title	= strip_tags($Page->data->content);
		}	
    }
	
	
	
	static public
    function controller(&$Page)
    {
		// делаем www-редирект,  при необходимости
		$domain = $_SERVER['HTTP_HOST'];
		$is_www = (bool)strstr('^'.$domain, '^www.');
		$need_www = (bool)val(self::$Config->need_www);
		
		
		
		if( $is_www != $need_www // если домен не соответствует основному
			&& strstr($domain, '.') // и это - не локальный сайт
			) // делаем редирект 
		{
			// очищаем домен от www
			$domain = str_replace(array('^www.','^'),'',  '^'.$domain);
			
			// формируем новый правильынй URL страницы
			$url = 'http://'.($need_www ? 'www.' : '') .$domain . $_SERVER['REQUEST_URI'];
		
		// pr($url);
		
			// редиректим
			redirect301($url);
			exit;
		}
		// pr($url);
		
		
		
		
		$action = Core::$Request->action;
		
		// Инициализируем дефолтные свойства страницы 
		$Page->title 	 	= 
		$Page->site_title	= strip_tags( self::$Config->site_title );
		
		$Page->description 	= strip_tags(html(self::$Config->site_description));
		
		$Page->design_dir 	= self::$Config->design_dir;
		$Page->design_url 	= self::$Config->design_url;
		$Page->images_url	= is_dir($dir = $Page->design_dir.'/images')
								? ($Page->design_url.'/images') 
								: (is_dir($dir = $Page->design_dir.'/img')
									? ($Page->design_url.'/img')  
									: '');
								
		//pr($Page);
		// $Page->page_template = find_file_exists(
								// "$Page->design_dir/page {$action}.php",
								// "$Page->design_dir/page.php"
								// );        
		
		// вычисляем шаблон дизайн дял старницы
		$template_id=GET('template');
		$Page->page_template = find_file_exists(
								"$Page->design_dir/page {$template_id}.php",
								"$Page->design_dir/page.php"
								);        
		
		
		
		$Page->content_template = find_file_exists(
								"$Page->design_dir/page_content {$action}.php",
								"$Page->design_dir/page_content.php"
								); 

		
		// $Page->theme_dir 	= self::$Config->theme_dir;
		// $Page->theme_url 	= self::$Config->theme_url;
		
		
		
		
		// $Page->page_template = find_file_exists(
								// "$Page->theme_dir/page {$action}.php",
								// "$Page->theme_dir/page.php"
								// );        
		
		// $Page->content_template = find_file_exists(
								// "$Page->theme_dir/page_content {$action}.php",
								// "$Page->theme_dir/page_content.php"
								// );        
		// 
		// pr(
			// (int)file_exists("$Page->theme_dir/page_content_{$action}.php"),
			// (int)file_exists("$Page->theme_dir/page_content.php")
			// , $Page);      
		
		// вычисляем id страницы
		if ($action=='index')
		{
			$Page->is_index = true;
			$Page->id = Site::get_index_page_id(); 
		}	
		else
		{
			$Page->is_index = false;
			$Page->id =  self::urlpath2id(Core::$Request->path);
		}
		
		
		if (!$Page->id) 
			return self::action_error404($Page);
		else	
			return self::action_page($Page);
	}
    
    
    
    /**
     * index_page_id($id=null) - возвращает id для главной страницы сайта. 
     *      Если в настройках сайта  выбрана главная страница и эта страница существует - возвращает её id, иначе - возвращает id первой (при сортировке по priority) существующей и нескрытой страницы верхнего уровня
     */
    static public
    function get_index_page_id()
    {
        static $index_page_id;
		if ($index_page_id) return $index_page_id;
        
		
		
		$id = self::$Config->index_page_id;
		
        if ($id && Db::get_var('SELECT id FROM #site_pages WHERE id=?', intval($id)))
            $index_page_id = $id;
        else    
            $index_page_id = Db::get_var('SELECT id FROM #site_pages WHERE show=1 AND parent_id="" ORDER BY position LIMIT 1');
        
		//pr(Db::get_results('SELECT * FROM #site_pages WHERE parent_id=""   ORDER BY position LIMIT 1'));
		//echo "index_page_id='$index_page_id'<br/>";
		
        return $index_page_id;
        
    }
	
	static public
    function page_exists($urlpath)
    {
		return $page_id = self::urlpath2id($urlpath);
		 
    }   
   
    static public
    function page_exists_id($page_id)
    {
		
        
		return true;
    }
    
    static public
    function page_access($page_id, $User)
    {
    
        return true;
    }
    
	static public
    function get_page_default()
    {
		$page = (object) array('show'=>1,);
		
		
		// TODO:: заменить на свойство из конфига дизайна Core::$Design OR Site::$Design OR Config('design')
		$page->show_in_menu = val(Site::$Theme->menu_defaults);
		
		
		$page->position = 10+(int)Db::get_var('SELECT MAX(position) FROM #site_pages');
		
		//pr(10 + Db::get_var('SELECT MAX(position) FROM #site_pages'));
		//pr($page);
		
		return $page;
	}
	
    static public
    function get_page($page_id)
    {
        if(!$page_id) return false;
		
		// извлекаем свойства страницы из базы 
        $pg = Db::get_row('SELECT * FROM #site_pages WHERE id=?', intval($page_id));
        if(!$pg) return false;
		
		// преобразуем некоторые поля в правильный формат
		
		// виджеты десериализуем в массив
		// (:TODO: в будущем нужно оптимизировать содержимое колонки #site_pages.widgets - для быстрого поиска страницы с нужным модулем-виджетом (или создать отдельную таблицу)
		$pg->widgets = unserialize($pg->widgets);
        if (!$pg->widgets) $pg->widgets = array();
		
		// списко меню превращаем в массив  
		$pg->show_in_menu = explode(',', trim($pg->show_in_menu,','));
        
        // вычисляем URL-адрес на страницу 
        $pg->url = Site::get_index_page_id() == $pg->id ?
                    '/' : Core::get_url('site','page', Site::id2urlpath($pg->id));

		// приводим к целому - позицию страницы
		$pg->position = intval($pg->position);
		
		
		// корректируем пути к картинкам 
		// (это нужно, если ранее пути были заданы в контексте другого сайта или сменились системные папки и пути)
		
		// обрабатываем иллюстрацию страницы
		if ($pg->img && $pg->img[0]=='/' 
			&& $i=strstr($pg->img, '/data/') 
			    // отрезаем префикс перел /data/
			)
			{
				// добавляем правильный префикс для текущего сайта
				$pg->img = SITE_ROOT_URL . $i;
			}
		
		// обрабатываем картинки в коде страницы
		if (strstr($pg->content, '/data/')
			&& 	stristr($pg->content, '<img')
			)
			{
				// исправляем неправильыне пути к картинкам и файлам 
				// подставляем SITE_ROOT_URL вместовсего, что стоит перед "/data/" в занчениях атрибутов ссылок и картинок
				// :TODO: сейчас нет ограничений на кон\кретный тег и атрибут, так что могут быть ложные срабатывания, нужно оптимизировать в будущем 		
				$pg->content = preg_replace( 
					array('@=\s*["\'][^"\']*/data/@i'), 
					array('="'.SITE_ROOT_URL.'/data/'), 
					$pg->content );
					
				// pr($pg->content);	

			}
		
		
		
		
        return $pg;
    }
    
	static public
    function save_page($page_data)
    {
		
		if (!empty($page_data->show_in_menu))
			$page_data->show_in_menu = ','. implode(',', $page_data->show_in_menu) .',';
		
		if (!empty($page_data->widgets))
			$page_data->widgets = serialize($page_data->widgets);	
		
		
		// pr($page_data);
		
		
		$page_data->urlword = trim($page_data->urlword);
		
		// если urlword не задан -  генерируем его из title путем транслитерации и фильтрации 
		if( !$page_data->urlword )
			$page_data->urlword = Filter::urlword($page_data->title);
		
		// если страница с таким urlword уже есть - добавляем уникальный цифровой суффикс
		$page_data->urlword = Db::make_unique(
						'#site_pages', 'urlword',
						$page_data->urlword,
						$page_data->id
						);
		
		// pr($page_data);
		
		
		$row_id = Db::save_row('#site_pages', $page_data);
		
		
		return $row_id;
	}
	
	static public
    function delete_page($page_id)
	{
		// ищем все дочерние страницы
		$del_ids = array( intval($page_id) );
		$i=0;
		while ($i < count($del_ids))
		{
			$parent_id = $del_ids[$i];
			$childrens = Db::get_col('SELECT id FROM #site_pages WHERE parent_id = ?', $parent_id);
			//pr($childrens);
			
			if ($childrens) $del_ids = array_merge($del_ids,$childrens);
			//pr($del_ids);
			
			$i++;
		}
		//pr($del_ids);
		
		Db::query('DELETE FROM #site_pages WHERE id IN (?) ', $del_ids );
		
	}
	
	static public
    function toggle_page($page_id)
	{
		Db::query('UPDATE #site_pages SET show = 1-show WHERE id=? ', intval($page_id));
		
	}
	
	static public
    function page_position($page_id, $position)
	{
		Db::query('UPDATE #site_pages SET position=? WHERE id=? ', 
				   intval($position), intval($page_id)
		);
		
	}
	
	static public
    function page_url($page_id)
	{
		return self::get_page_url($page_id);
	}
	
	
	static public
    function get_page_url($page_id)
	{
		return Core::get_url('site','page', self::id2urlpath($page_id));
	}
	
	
    static public
    function id2urlpath($page_id)
    {
        $pages_list = & self::get_pages();
		//pr($pages_list);
		
		if  (	$page_id == self::get_index_page_id()
				OR !isset($pages_list[$page_id]) 
			) 
			return '';
        
		
        // строим цепочку 'urlword/urlword/urlword' от потомка к родителям
        $page    = $pages_list[$page_id];
        $urlpath = $page->urlword;
        $maxparents=20; // неболее 20 родителей (для защиты от зацикливания)
        
        while ( ($page_id=$page->parent_id) 
                && isset($pages_list[$page_id]) 
                && --$maxparents
              )
            {
                
                $page    = $pages_list[$page_id];
                $urlpath =  $page->urlword . '/' . $urlpath;
            }
        
        return $urlpath;
        
    }
    
    
    
    
    
    static public
    function urlpath2id($urlpath)
    {
        if (!$urlpath) return index_page_id();
       
        $c = count($sections = explode('/',$urlpath));
        //pr($sections);
        
        $parent_pg = (object)array('id'=>0, 'parent_id'=>0);
        
        foreach ($sections as $section)
        {
            $pg = Db::get_row('SELECT id, parent_id, urlword FROM #site_pages WHERE urlword=?', $section);
            if (empty($pg->id) || $pg->parent_id != $parent_pg->id) return false;
            
            $parent_pg = $pg;
        }
        
        //pr($pg);
        return $pg->id;
    }
    
    
	
	
	static public
    function get_themes()
	{
		$result = array();
		$themes = dir_list(THEMES_DIR);
		foreach ($themes as $t_id)
		{
			$t_conf = THEMES_DIR ."/$t_id/design_config.php";
			
			if (file_exists($t_conf))
			{
				$theme = (object) read_array($t_conf);
				$theme->id = $t_id;
				if (empty($theme->title)) $theme->title = $theme->id;
				
				$result[] = $theme;
			}
		}	
		return $result;	
	}
	
    
    // кеш-массив для полного списка страниц
    static $pages_list = array();
	
    static public
    function &get_pages()
    {
        
		//Db::col_create('#site_pages', 'urlword_rewrite');
		
		
		$pages_list =& self::$pages_list;
		
		if ($pages_list) return $pages_list;
        
		$where = User::$User->is_admin ? '1' : ' show=1 ';
        $pages = Db::get_results(
				   "SELECT " .self::$pages_list_fields. " 
					FROM #site_pages 
					WHERE $where 
					ORDER BY 0+parent_id, position, title
					");
		//pr($pages);
       
        // создаем массив страниц с простым доступом к группам страниц по их 'parent_id'
        if($pages)
		foreach($pages as $page)
		{
			// TODO: вынести в отдельную функцию - подготовку данных страницы для сайта, так как используется здесь и ещё в get_page
			
			$page->show_in_menu =  explode(',',  trim( $page->show_in_menu ,',') );
            $page->show      = $page->show ? 1 : 0;  
            $page->position = intval($page->position);
			
			$page->parent_id    = intval($page->parent_id)	;
            $page->widgets		= unserialize($page->widgets);
			
            $childrens[$page->parent_id][] = $page;
            
		}
		unset($page);
        //pr($childrens);
		
		// теперь обработаем все корневые страницы и добавим к ним в списком все дочерние элементы в том порядке, как они должны идти в дереве
		
		$i=0; 
		$level= array(0 => 1); 
		while (isset($childrens[0][$i]))
		{
			// добавляем в конечный список страниц текущую страницу 
			$page =& $childrens[0][$i];
			$pages_list[$page->id] = $page;
			
			// указываем уровень страницы в иерархии страниц
			$page->level = $level[$page->parent_id];
			
			// если существуют дочерние страницы по отношению к текущей 
			if ($page->id && isset($childrens[$page->id]))
			{
				// вставляем все дочерние стсраницы после текущей, 
				// (для дальнейшей обработки)    
				array_splice($childrens[0] , $i+1, 0, 
					$childrens[$page->id] );
				// подгатавливаем уровень для страниц-детей данного родителя 
				$level[$page->id] = $page->level+1 ;
			}	
			
			$i++;
		}
		unset($page);
		// pr($pages_list);
		
		
        // теперь, когда весь массив страниц сохранен, вычисляем URL для каждой страницы (с учетом urlword  родительских страниц)
        foreach($pages_list as &$page)
		{
            // pr($page);
			$page->url_original = Core::get_url('site','page', Site::id2urlpath($page->id)); 
			
			if (val($page->url_rewrite))
				$page->url = $page->url_rewrite;
			 else	
				$page->url = $page->url_original;
			
		}
        // pr($pages_list); 
        
        return $pages_list;
    }
        
            
          
	
	
	static
	function widget_menu_($params)
	{
		// pr($params);
		
		return self::get_menu();
	}
	
    

    /** !!! Эта функция больше не используется. Вместо неё - View::menu() 
	 *
     * get_menu($params) - выводит иерархическое меню навигации с использованием заданного шаблона и параметров
     * 
     * @param array $params - массив с параметрами и шаблонами для построения меню
     * @return string - возвращает HTML код меню
     *
     * Массив $params может содержать следущие элементы: 
     * 
       <code>
       $params = array(
           'is_admin'   => 1,  // (необязательно) если 1, то выводятся скрытые страницы
           'menu_id'    => 'topmenu', // (необязательно) выбирать страницы только указанного меню (идентификаторы меню описываются в теме дизайна в файле theme_info.php)
           'parent_id'  => 0,   // (необязательно) id корневой страницы для меню, по умолчанию меню строиться от корня сайта
           'prefix'     => '<ul class=level%level% >', // (необязательно) префикс перед списком элементов; %level% заменяется на число - уровень вложенности меню (начиная с 1)
           'suffix'     => '</ul>', // (необязательно) суффикс после списка элементов; %level% заменяется на число - уровень вложенности меню (начиная с 1)
           
           'unactive'   => '<li><a href="%url%" >%title%</a>', // (обязательно) шаблон для обычного пункта меню; макропеременные %varname%  заменяются на соответствующие свойства страницы (url, title, tooltip, img, show и другие); %submenu% заменяется на HTML код вложенного меню (если есть) или пустую строку.  
           
           'active'     => '<li><a href="%url%" class=active >%title%</a>', // (необязательно, если не указано, то используется шаблон  'unactive') шаблон для активного пункта меню (т.е. совпадает с текущей страницей); макропеременные %varname%  заменяются на соответствующие свойства страницы (url, title, tooltip, img, show и другие); %submenu% заменяется на HTML код вложенного меню (если есть) или пустую строку.  
           
           'divider' => "\n", // (необязательно) разделитель между элементами меню
           
           'sub_templates'=>array(...),  // (необязательно) шаблоны для вложенных меню; если не указано, то используются исходные шаблоны; этот массив также может содержать элемент 'sub_templates' (с шаблонами для меню 3го уровня), и т.д.
                            
        
        );
        </code>
    ***/
	
	static  // корректирующая заглушка для старой версии 
	function get_menu($params)
	{
		
		
		$params['return']=1;
		$params['add_submenu']=1;
		
		foreach ($params as &$val)
			$val=str_replace('%level%','%depth%', $val);
		
		//pr($params);
			
		return View::menu($params);
	}

/* 
    static public
    function get_menu_old($params, $pages_list=null)
    {
        
		// инициализируем исходные параметры и шаблоны для построения меню
        $params_default = array( 
            'is_admin'   => 0,  
            'menu_id'    => '', 
            'parent_id'  => 0,   
            'prefix'     => '', 
            'suffix'     => '', 
            'unactive'   => '', 
            'active'     => '', 
            'divider' => '', 
            'level' => 1,
            'sub_templates' => null,
            );
        $params = array_merge($params_default, $params);  // устанавливаем неуказанные свойства  
        //pr($params);

        if (!$params['active']) $params['active'] = $params['unactive']; // устанавливаем шаблон для активного пункта 
        
        // устанавливаем шаблоны и исходные параметры для подменю
        if (!$params['sub_templates'])  $params['sub_templates']=$params; 
        $params['sub_templates']['is_admin'] = $params['is_admin'];
        $params['sub_templates']['menu_id'] = $params['menu_id'];
        $params['sub_templates']['level'] = $params['level'] + 1;
        //pr($params);
        
        // начинаем сбор HTML кода меню
        $result = ''; 
        
        // прибавляем префикс, указывая в нём уровень вложенности меню
        $result .= str_replace('%level%', $params['level'], $params['prefix']);
        
        // определяем ID текущей страницы
        
        $cur_id = Core::$Page->id;
		//empty($Page->id)? 0 : $Page->id;
        
        //pr($params);
		
        $count=0; // счетчик пунктов меню
        
        // получаем массив со страницами
		if (!$pages_list) $pages_list = Site::get_pages();
		
		 
		
		
		// перебирем все страницы и только нужные добавляем в меню
        foreach($pages_list as $page)
        {
            //pr(count($pages_list));
			
			
			$page = (array)$page;
            
			
			
            // пропускаем страницы, у которых menu_id не соответсвтующие заданному в параметрах меню 
            if ($params['menu_id'] && !in_array($params['menu_id'], $page['show_in_menu'])) continue;
            
			// пропускаем страницы, у которых parent_id не соответсвтует заданному в параметрах меню 
            if($page['parent_id'] != $params['parent_id']) continue;
            
			//pr($page[show]);
			//pr( !$params['is_admin'] , !$page->show);
			
			// если не админ-режим - то скрытые страницы не показываем
			if (!$params['is_admin'] && !$page['show']) continue;
			

			
            $count++; // считаем пункты меню
            
            if ($count > 1) $result .= $params['divider']; // перед всеми пунктами кроме 1го, вставляем разделитель ( divider )
            
			
			
            // определяем шаблон для отображения пункта меню
            $item = ($page['id'] == $cur_id) ? $params['active'] : $params['unactive'];
			if (!$page['show'] && isset($params['hidden']))
				$item = $params['hidden'];
            
            // заменяем макропеременные в шаблоне на соответсвтующие свойства обрабатываемой страницы
            // (для расширяемости не указываем конкретных свойств)
			
			
            foreach ($page as $prop => $val)
            {
                if (is_array($val)) continue;
				$item = str_replace('%'.$prop.'%' , $val, $item);
            }
            
			
			
			// вычисляем под-меню для обрабатываемой страницы       
            $params['sub_templates']['parent_id'] = $page['id'];
			
            $submenu = self::get_menu($params['sub_templates'], $pages_list);
			
			
			
			// :TODO: в начале функции нужно вычислять static array $pages_list_parent_id
            // и вычислять $submenu ТОЛЬКО в том случае, если текущий parent_id 
            // присутствует в списке $pages_list_parent_id
            
            
            // если подменю имеется, то вставляем вместо %submenu% или прибавляем его в конец $item
            if ($submenu)
            {
                if (strstr($item, '%submenu%'))
                    $item = str_replace('%submenu%',$submenu, $item);    
                else
                    $item .= $submenu;
            }
            
            // добавляем пункт меню (вместе с под-меню) к результирующему HTML коду
            $result .= eval_phtml($item);
			// $result .= $item ;

        }
        
		
		
        // добавляем к результату суффикс (при необходимости парсим %level%)
        $result .= str_replace('%level%', $params['level'], $params['suffix']);
        
        //pr($result);
        
        // если пукты меню имеются - возвращаем их, инчае - пустую строку
        return $count > 0 ? $result : '';

    }
	 */
	

	
	// !!! этот хук не используется - так как URL-запросы к файлам сайта корректируются через htaccess
	// корректиирует пути к файлам сайта (со старого формата /data/ на новый /sites/<site_id>/data/), заменяем старые пути к картинкам на новые - с поддержкой мультидоменности
	static
	function rewrite_sitefiles() 
	{
		//pr(DATA_URL, DESIGN_URL );
		
		Core::$Page->document = preg_replace(
			
			array(
				'~(=\s*[\'\"\s]?)/data/~',
				'~(=\s*&quot;\s*)/data/~',
				'~(=\s*[\'\"\s]?)/design/~',
				'~(=\s*&quot;\s*)/design/~',
			),
			
			array(
				'$1'.DATA_URL.'/',
				'$1'.DATA_URL.'/',
				'$1'.DESIGN_URL.'/',
				'$1'.DESIGN_URL.'/',
			),
						
			Core::$Page->document 
		);
	}
	 
	// кодирует все e-mail в документе, для защиты от спам-роботов 
	static
	function encode_document_emails() 
	{
		$Page =& Core::$Page;
		
		//if(Core::$Request->module =='admin') return;
		
		Core::$Page->document = self::encode_emails(Core::$Page->document); 
	}
	
	
	// Защищает-кодирует все e-mail-ы  в виде ссылок или обычного текста 
	static
	function encode_emails($html) 
	{
		// простая проверка на отсутствие email, которые нужно ли кодировать 
		if(!strstr($html,'@')) return $html;
		
		// подготавливаем массив строк дял поиска и замены
		$regexp=$replace=array();
		
		// заменяем email-ссылки, содержащие в тексте e-mail
		$regexp[] 	= 
		'/'
			.'<a([^>]+)'			// $1
			.'mailto:'
			.'([\w\.\-_]{2,256})'  	// $2
			.'@'
			.'([\w\.\-_]{2,256})'  	// $3
			.'(\.[\w]{2,5})'		// $4
			.'([^>]*)>\s*'				// $5
				.'([\w\.\-_]{2,256})'  	// $6
				.'@'					// @ => &#64;
				.'([\w\.\-_]{2,256})'  	// $7
				.'(\.[\w]{2,5})'		// $8
			.'\s*<\/a>'
		.'/siUe';
		
		$replace[] = '\'
		<script> 	
			wr = function(str){document.write(str)};
			wr("<" +"A $1"+"mai"); 
			wr("lto:$2" 
					+ "&#"+"64;" 
					+"$3"  +"$4"  +"$5 >"	);
			wr("$6" + "&#6"+"4;" +"$7"  +"$8")
			wr("</" +"a>");
		</script>
		<noscript> \' . mb_encode_numericentity(
						"$2 {at} $3$4" ,
						array(0x0000, 0xffff, 0, 0xffff), "UTF-8" )
					  . \'</noscript>\'
		';
		
		
		// заменяем email-ссылки, НЕ содержащие в тексте e-mail
			
		$regexp[] 	= 
			'/'
			.'<a([^>]+)'			// $1
			.'mailto:'
			.'([\w\.\-_]{2,256})'  	// $2
			.'@'
			.'([\w\.\-_]{2,256})'  	// $3
			.'(\.[\w]{2,5})'		// $4
			.'([^>]*)>'				// $5
			.'(.*)'					// $6
			.'<\/a>'
		.'/siU';
		
		$replace[] = '
			<script>
			wr=document.write;
			wr("<A $1"+"mai");
			wr(	 "lto:$2"
				+"&#"+"64;" // @
				+"$3"
				+"$4"
				+"$5 >"
				);
			</script>$6<script>wr("</a>");</script>
			';
		
		
		// кодируем чисто-текстовые (без ссылки) e-mail 
		 $regexp[] 	= 
			'/'
				.'([\w\.\-_]{2,256})' //1
				.'@'				  	
				.'([\w\.\-_]{2,256})' //2
				.'(\.[\w]{2,5})'	  //3	
			.'/siUe'; 
		
		$replace[] = ' 
			\'<script>document.write("\'
			. mb_encode_numericentity(
						"$1@$2$3" ,
						array(0x0000, 0xffff, 0, 0xffff), "UTF-8" )
			.\'")</script>
			<noscript>\'.
				mb_encode_numericentity(
						"$1{at}$2$3" ,
						array(0x0000, 0xffff, 0, 0xffff), "UTF-8" )
			.\'</noscript>	
			\'	
			';
		
		// вырезаем области кода и контейнеры тегов, в которых не нужно заменять e-mail на скриптовый вывод:  SCRIPT, TEXTAREA, INPUT
		$save_code_exists = (bool)(
				  stristr($html,'<script') 
				. stristr($html,'<textarea') 
				. stristr($html,'<input')
				// title= , alt= , 
			);
		
		//var_dump($save_code_exists);exit;
		
		
		if ($save_code_exists)
		{
			$code1=$code2=$code3=
			$code_save=array();
			$code_placeholders=array();
			
			preg_match_all('`<textarea[^>]*>(.*)</textarea>`isU',$html,$code1);
			preg_match_all('`<script[^>]*>(.*)</script>`isU',$html,$code2);
			preg_match_all('`<input[^>]*>`isU',$html,$code3);
			
			$code = array_merge($code1[0], $code2[0], $code3[0]);
			
			for($i=0;$i<count($code);$i++){
				$html=str_replace($code[$i], "[noEncodeEmail-$i]",$html);
				$code_save[]=$code[$i];
				$code_placeholders[]= "[noEncodeEmail-$i]";
			}
			// pr($code_placeholders, $code_save);
		}
		
		// выполняем подготовленные замены
		$html=preg_replace($regexp, $replace, $html);
		
		
		if ($save_code_exists)
		{
			// возвращаем все секции скриптов
			$html=str_replace($code_placeholders,$code_save,$html);
			
		
			// теперь кодируем e-mail внутри скриптов (без ущерба для кода)
			$html=preg_replace(
					'/[\w\.\-_]{2,256}@[\w\.\-_]{2,256}\.[\w]{2,5}/sie', 
					'mb_encode_numericentity( "$0" ,
							array(0x0000, 0xffff, 0, 0xffff), "UTF-8" )
					', 
					$html);
		}
		
		return $html;	
		
	}
}

	
	
